<template>
  <el-container>
    <!-- 左侧菜单栏 -->
    <el-aside width="300px" v-loading="data.menuloading">
      <el-container>
        <el-header>
          <el-input
            placeholder="输入关键字进行过滤"
            v-model="data.menuFilterText"
            clearable
          ></el-input>
        </el-header>
        <el-main class="nopadding">
          <el-tree
            ref="menuRef"
            class="menu"
            node-key="id"
            :data="data.menuList"
            :props="data.menuProps"
            draggable
            highlight-current
            :expand-on-click-node="false"
            check-strictly
            show-checkbox
            :filter-node-method="menuFilterNode"
            @node-click="menuClick"
            @node-drop="node_drag"
            :allow-drop="allow_drop"
          >
            <template #default="{ node, data }">
              <span class="custom-tree-node">
                <span class="label">{{ node.label }}</span>
                <span class="do" v-if="node.level < 2">
                  <el-button
                    icon="el-icon-plus"
                    size="small"
                    @click.stop="add(node, data)"
                  ></el-button>
                  <!-- <el-icon size="small">
                    <el-icon-plus />
                  </el-icon> -->
                </span>
              </span>
            </template>
          </el-tree>
        </el-main>
        <!-- 左侧树按钮栏 -->
        <el-footer style="height: 51px">
          <el-button
            type="primary"
            size="small"
            icon="el-icon-plus"
            @click="add()"
          ></el-button>
          <el-button
            type="danger"
            size="small"
            plain
            icon="el-icon-delete"
          ></el-button>
        </el-footer>
      </el-container>
    </el-aside>
    <!-- 右侧 -->
    <el-container>
      <el-main class="nopadding" style="padding: 20px" ref="mainRef">
        <save ref="saveRef" :menu="data.menuList" @on-save="updateMenu"></save>
      </el-main>
    </el-container>
  </el-container>
</template>
<script setup lang="ts">
import { menuDataType } from './type';
import userApi from '@/api/user/index';
import menuApi from '@/api/menu/index';
import { reactive, ref, unref, watch } from 'vue';
import save from './components/save.vue';
import { ElMessage } from 'element-plus';
var menuRef = ref();
var saveRef = ref();
var mainRef = ref();
let data = reactive<menuDataType>({
  menuloading: false,
  menuList: [],
  menuProps: {
    label: (data: any) => {
      return data.meta.title;
    },
  },
  menuFilterText: '',
  temporaryId: '',
});
/**
 * 获取当前用户的菜单
 */
const getMenus = async () => {
  // var menus = await userApi.userMenus.post();
  var res = await menuApi.getmenus.post();
  data.menuList = res.data;
};
// menuFilterText(val) {
//       this.$refs.menu.filter(val);
//     },
watch(
  () => data.menuFilterText,
  (val: any) => {
    unref(menuRef).filter(val);
  }
);
//树过滤
const menuFilterNode = (value: any, data: any) => {
  if (!value) return true;
  var targetText = data.meta.title;
  return targetText.indexOf(value) !== -1;
};
const menuClick = (data: any) => {
  unref(saveRef).setData(data);
  unref(mainRef).$el.scrollTop = 0;
};
/**
 * 拖拽时判定目标节点能否成为拖动目标位置
 * @param draggingNode 拖拽当前节点
 * @param dropNode 拖拽完成的节点
 * @param type type 参数有三种情况：'prev'、'inner' 和 'next'，分别表示放置在目标节点前、插入至目标节点和放置在目标节点后
 */
const allow_drop = (draggingNode: any, dropNode: any, type: any) => {
  if (draggingNode.childNodes.length > 0) {
    ElMessage.warning('不允许有子集的节点进行拖拽');
    return false;
  } else {
    return true;
  }
};
//拖拽成功完成时触发的事件
/**
 * 共四个参数，依次为：被拖拽节点对应的 Node、结束拖拽时最后进入的节点、被拖拽节点的放置位置（before、after、inner）、event
 */
const node_drag = (
  currentNode: any,
  nextNode: any,
  location: any,
  event: any
) => {};
const updateMenu = (id: any) => {
  getMenus();
  unref(menuRef).setCurrentKey(id);
  let newData = unref(menuRef).getCurrentNode();
  unref(saveRef).setData(newData);
};
let newMenuIndex = 1;
const add = async (node: any = '', data: any = '') => {
  // 将临时菜单添加到页面中
  let temporaryId = randomString(5);
  var newMenuName = '未命名' + newMenuIndex++;
  var newMenuData = {
    parentId: data ? data.id : '',
    name: newMenuName,
    number: 0,
    path: '',
    component: '',
    // auth: [],
    meta: {
      title: newMenuName,
      type: 'menu',
    },
    id: temporaryId,
  };
  unref(menuRef).append(newMenuData, node);
  unref(menuRef).setCurrentKey(newMenuData.id);
  unref(saveRef).setData(newMenuData, 'add');
};
// 随机数方法，在新增菜单中调用
const randomString = (len: any) => {
  len = len || 10;
  let $chars =
    'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678'; /****默认去掉了容易混淆的字符oOLl,9gq,Vv,Uu,I1****/
  let maxPos = $chars.length;
  let id = 'linshi-';
  for (let i = 0; i < len; i++) {
    id += $chars.charAt(Math.floor(Math.random() * maxPos));
  }
  return id;
};
/**
 * 页面加载时就会调用的方法
 */
getMenus();
</script>
<style scoped>
.menu:deep(.el-tree-node__label) {
  display: flex;
  flex: 1;
  height: 100%;
}
.custom-tree-node {
  display: flex;
  flex: 1;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  height: 100%;
  padding-right: 24px;
}
.custom-tree-node .label {
  display: flex;
  align-items: center;
  height: 100%;
}
.custom-tree-node .label .el-tag {
  margin-left: 5px;
}
.custom-tree-node .do {
  display: none;
}
.custom-tree-node .do i {
  margin-left: 5px;
  color: #999;
}
.custom-tree-node .do i:hover {
  color: #333;
}

.custom-tree-node:hover .do {
  display: inline-block;
}
</style>
